#include "../include/bitmap.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
    Bitmap结构体定义
*/
struct _Bitmap {
  char *bits;           // char类型的动态数组
  unsigned int length;  // bitmap表示的最大长度
};

Bitmap *bitmap_create(unsigned int length, unsigned char value) {
  Bitmap *bits = (Bitmap *)malloc(sizeof(Bitmap));

  if (bits == NULL) {
    printf("allocate failure!\n");
    return NULL;
  }

  // 需要分配的字节数
  unsigned int numbits = sizeof(char) * (length >> 3) + 1;

  // 分配capicity字节的char类型连续空间
  bits->bits = (char *)malloc(numbits * sizeof(char));
  if (bits->bits == NULL) {
    printf("Allocate failure!\n");
    free(bits);
    return NULL;
  }

  memset(bits->bits, value, numbits);

  bits->length = length;

  return bits;
}

void bitmap_destory(Bitmap **bits) {
  if (*bits == NULL) return;

  free((*bits)->bits);
  free(*bits);
  // 将bits置位为NULL
  memset(bits, 0, sizeof(Bitmap *));
}

bool bitmap_set(Bitmap *bits, unsigned int pos, unsigned char value) {
  // pos大于length时，非法地址，返回false，其他返回true
  if (pos >= bits->length) {
    return false;
  }

  unsigned char mask = 0x80 >> (pos & 0x7);

  if (value) {
    // 置位为1
    bits->bits[pos >> 3] |= mask;
  } else {
    // 复位为0
    bits->bits[pos >> 3] &= ~mask;
  }

  return true;
}

bool bitmap_get(Bitmap *bits, unsigned int pos, unsigned int *value) {
  if (pos >= bits->length) {
    return false;
  }

  unsigned char mask = 0x80 >> (pos & 0x7);

  if ((bits->bits[pos >> 3] & mask) == mask) {
    *value = 1;
  } else {
    *value = 0;
  }

  return true;
}

unsigned int bitmap_length(Bitmap *bits) { return bits->length; }